package com.tsunami.auth.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tsunami.auth.service.auth.*;
import com.tsunami.authority.dto.auth.*;
import com.tsunami.authority.entity.auth.Role;
import com.tsunami.authority.entity.auth.RoleAuthority;
import com.tsunami.authority.entity.auth.UserRole;
import com.tsunami.authority.enums.auth.AuthorizeType;
import com.tsunami.base.R;
import com.tsunami.base.entity.SuperEntity;
import com.tsunami.log.annotation.SysLog;
import com.tsunami.user.annotation.LoginUser;
import com.tsunami.user.model.SysUser;
import com.tsunami.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Classname RoleController
 * @Description TODO
 * @Date 2021-10-30 9:22
 * @Created by lx
 */
@RestController
@RequestMapping("/role")
@Api(value = "Role", tags = "角色管理")
public class RoleController {

    @Autowired
    private IRoleService roleService;
    @Autowired
    private IRoleOrgService roleOrgService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleAuthorityService roleAuthorityService;
    @Autowired
    private IUserRoleService userRoleService;

    @GetMapping("/page")
    @ApiOperation(notes = "角色列表（分页）",value = "获取角色列表")
    @SysLog("获取角色列表")
    public R page(Integer pageNum,
                  Integer pageSize,
                  String orderByColumn,
                  String isAsc,
                  RolePageDTO data){
        return roleService.selectPageList(data);
    }

    @ApiOperation(value = "查询角色", notes = "查询角色")
    @GetMapping("/get")
    @SysLog("查询角色")
    public R get(Long id) {
        Role role = roleService.getById(id);

        RoleQueryDTO roleQueryDTO = new RoleQueryDTO();
        List<Long> orgList = roleOrgService.listOrgByRoleId(role.getId());
        roleQueryDTO.setOrgList(orgList);
        return R.ok().data(orgList);
    }

    @ApiOperation(value = "检测角色编码", notes = "检测角色编码")
    @GetMapping("/check")
    @SysLog("检测角色编码")
    public R check(@PathVariable String code) {
        Boolean result = roleService.check(code);
        return R.ok().only(result);
    }

    /**
     * 新增角色
     */
    @ApiOperation(value = "新增角色", notes = "新增角色不为空的字段")
    @PostMapping("/save")
    @SysLog("新增角色")
    public R save(@LoginUser SysUser user, @Validated RoleSaveDTO data) {
        roleService.saveRole(data, user.getId());
        return R.ok();
    }

    /**
     * 修改角色
     */
    @ApiOperation(value = "修改角色", notes = "修改角色不为空的字段")
    @PutMapping("/update")
    @SysLog("修改角色")
    public R update(@LoginUser SysUser user, RoleUpdateDTO data) {
        roleService.updateRole(data, user.getId());
        return R.ok();
    }

    /**
     * 删除角色
     */
    @ApiOperation(value = "删除角色", notes = "根据id物理删除角色")
    @PostMapping("/delete")
    @SysLog("删除角色")
    public R delete(String ids) {
        if(StringUtils.isEmpty(ids)){
            return R.error();
        }
        String[] idss = ids.split(",");
        List<Long> idList = Arrays.stream(idss)
                .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        roleService.removeById(ids);
        return R.ok();
    }

    /**
     * 给用户分配角色
     */
    @ApiOperation(value = "给用户分配角色", notes = "给用户分配角色")
    @PostMapping("/user")
    @SysLog("给角色分配用户")
    public R saveUserRole(UserRoleSaveDTO userRole) {
        return R.ok().only(roleAuthorityService.saveUserRole(userRole));
    }

    /**
     * 查询角色的用户
     */
    @ApiOperation(value = "查询角色的用户", notes = "查询角色的用户")
    @GetMapping("/roleUser")
    @SysLog("查询角色的用户")
    public R findUserIdByRoleId(Long roleId) {
        QueryWrapper param = new QueryWrapper();
        param.eq("role_id",roleId);
        List<UserRole> list = userRoleService.list(param);
        return R.ok().data(list.stream().mapToLong(UserRole::getUserId).boxed().collect(Collectors.toList()));
    }

    /**
     * 查询角色拥有的资源id
     */
    @ApiOperation(value = "查询角色拥有的资源id集合", notes = "查询角色拥有的资源id集合")
    @GetMapping("/authority")
    @SysLog("查询角色拥有的资源")
    public R findAuthorityIdByRoleId(@PathVariable Long roleId) {
        QueryWrapper param = new QueryWrapper();
        param.eq("role_id",roleId);
        List<RoleAuthority> list = roleAuthorityService.list(param);
        List<Long> menuIdList = list.stream().filter(item -> AuthorizeType.MENU.eq(item.getAuthorityType())).mapToLong(RoleAuthority::getAuthorityId).boxed().collect(Collectors.toList());
        List<Long> resourceIdList = list.stream().filter(item -> AuthorizeType.RESOURCE.eq(item.getAuthorityType())).mapToLong(RoleAuthority::getAuthorityId).boxed().collect(Collectors.toList());
        RoleAuthoritySaveDTO roleAuthority = RoleAuthoritySaveDTO.builder()
                .menuIdList(menuIdList).resourceIdList(resourceIdList)
                .build();
        return R.ok().data(roleAuthority);
    }


    /**
     * 给角色配置权限
     */
    @ApiOperation(value = "给角色配置权限", notes = "给角色配置权限")
    @PostMapping("/authority")
    @SysLog("给角色配置权限")
    public R saveRoleAuthority(RoleAuthoritySaveDTO roleAuthoritySaveDTO) {
        return R.ok().only(roleAuthorityService.saveRoleAuthority(roleAuthoritySaveDTO));
    }


    /**
     * 根据角色编码查询用户ID
     */
    @ApiOperation(value = "根据角色编码查询用户ID", notes = "根据角色编码查询用户ID")
    @GetMapping("/codes")
    @SysLog("根据角色编码查询用户ID")
    public R findUserIdByCode(@RequestParam(value = "codes") String[] codes) {
        return R.ok().data(roleService.findUserIdByCode(codes));
    }

    /**
     * feign远程调用 根据账号获取用户
     * @param userId
     * @return
     */
    @RequestMapping(value="/findRolesByUser", method= RequestMethod.GET)
    R findRolesByUser(Long userId){
        List<Role> roleList = roleService.findRoleByUserId(userId);
        List<String> roleStr = roleList.stream()
                .map(item -> item.getId()+"_"+item.getCode()).collect(Collectors.toList());
        return R.ok().data(roleStr);
    }
}